package reflect;

import java.awt.geom.Arc2D;
import java.lang.reflect.*;
import java.nio.charset.StandardCharsets;

public class ClassAPI {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> clazz = Class.forName("reflect.Student");

        //此方法获取到的是当前类包括父类的所有的公有权限的属性
//        Field[] fields = clazz.getFields();
//        for (Field field : fields) {
//            System.out.println(field.getName());
//            System.out.println(field.getType());
//            System.out.println(field.getModifiers());
//            System.out.println("------");
//        }

       /* Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }
*/
        //此方法返回的是当前类的所有的属性，可以取到所有访问权限的属性
        Field address = clazz.getDeclaredField("grade");
        address.setAccessible(true);
        System.out.println(address.getName());
        System.out.println(address.getType().getName());
        Object o = clazz.newInstance();
//        Object d = 2;
//        Double d = 2.5;
        address.set(o, 2);
        System.out.println(((Student) o).getGrade());
//        String[] w={"北京市","天津市"};
//        address.set(o,w);
//        System.out.println(((Student)o).getAddress());

//        Field grade = clazz.getDeclaredField("grade");
//        grade.set(o,1222222);
//        System.out.println(((Student)o).getGrade());

        //获取该对象的普通方法，包含的方法范围是当前对象及父类所有的公有的方法
//        Method[] methods = clazz.getMethods();
//        for (Method method : methods) {
//            System.out.println(method.getName());
//        }

        //只获取该对象的类的普通方法，包含所有权限的方法
      /*  Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        declaredMethods[1].setAccessible(true);
        Object a="xff";
        Object d=5.0;
      //  Object o = clazz.newInstance();
        declaredMethods[1].invoke(new Student(),d,a);*/

        Student student=new Student();
        Method add = clazz.getDeclaredMethod("add", Double.class, String.class);
        add.setAccessible(true);
        Object a1="xff";
        double d1=5.0;
//      //  Object o = clazz.newInstance();
        add.invoke(student,d1,a1);


        //返回对象的所有的构造方法，只能获取公有的构造方法
//        Constructor<?>[] constructors = clazz.getConstructors();
//        for (Constructor<?> constructor : constructors) {
//            System.out.println(constructor.getName());
//        }


//        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
//        for (Constructor<?> declaredConstructor : declaredConstructors) {
//            System.out.println(declaredConstructor.getName());
//        }

//        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
//        declaredConstructor.setAccessible(true);
//        Object xff = declaredConstructor.newInstance("盐城", 1);
//        System.out.println(xff);


//        String st="xff";
//        System.out.println(st.hashCode());
//        Class<?> stringClass = Class.forName("java.lang.String");
//        Field value = stringClass.getDeclaredField("value");
//        value.setAccessible(true);
//
//        byte[] a = (byte[])value.get(st);
//        a=null;
//        value.set(st,"666xff".getBytes(StandardCharsets.UTF_8));
//        System.out.println(st);
//        System.out.println(st.hashCode());

//        Field s = clazz.getDeclaredField("s");
//        s.setAccessible(true);
//        System.out.println(s.getName());
//        Student o =(Student) clazz.newInstance();
////        String string = (String)s.get(o);
//        s.set(o,"666");//避开编译器的优化就可以对final的属性进行修改，可以利用三目运算private final String str= null==null?"abcd":null;或者在构造器为str赋值来避开优化
//        System.out.println(o.getS());
//
    }
}
